#include<func.h>

int main(int argc,char*argv[])
{
    // ./epoll_liaotian1 198.168.213.128 3333
    ARGS_CHECK(argc,3);
    //int sockfd = socket(AF_INET,SOL_SOCKET,0);//moren tmd zhelixiecuol 
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    //bind
    int flag = 1;
    int ret = setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag));
    ret = bind(sockfd,(struct sockaddr*)&addr,sizeof(addr));
    ERROR_CHECK(ret,-1,"bind");
    listen(sockfd,100);
    //epoll  fd_set
    int epfd = epoll_create(100);
    struct epoll_event event;
    event.events = EPOLLIN;//监听读
    event.data.fd = sockfd; //监听sockfd
    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);   //event 里面 data是联合体结构，我这里选fd，是检测到后往event里面放fd的数据
    //准备好用户态的就绪集合
    struct epoll_event readset[2]; //这里因为只是监听两个集合
    //netfd
    int netfd = -1;
    char buf[4096];
    while(1)
    {
        int readyNum = epoll_wait(epfd,readset,2,-1);
        for(int i=0;i<readyNum;i++)
        {
            //说明sockfd发消息了
            if(readset[i].data.fd == sockfd) 
            {
                netfd = accept(sockfd,NULL,NULL); //监听netfd
                //将netfd 加入监听
                event.events = EPOLLIN;
                event.data.fd= netfd;
                epoll_ctl(epfd,EPOLL_CTL_ADD,netfd,&event);
                event.events = EPOLLIN;
                event.data.fd= STDIN_FILENO;
                epoll_ctl(epfd,EPOLL_CTL_ADD,STDIN_FILENO,&event); //add stdin
                epoll_ctl(epfd,EPOLL_CTL_DEL,sockfd,NULL); //delete sockfd
            }
            else if(readset[i].data.fd == STDIN_FILENO)
            {
                //自己就绪
                bzero(buf,sizeof(buf));
                ssize_t sret = read(STDIN_FILENO,buf,sizeof(buf));
                if(sret == 0)
                {
                    //服务端结束
                    send(netfd,"nishigehaoren\n",15,0);
                    close(netfd);
                    //移除监听
                    epoll_ctl(epfd,EPOLL_CTL_DEL,netfd,NULL);
                    epoll_ctl(epfd,EPOLL_CTL_DEL,STDIN_FILENO,NULL);
                    event.events = EPOLLIN;
                    //我给对面发 不代表我结束了 如果不写这个了 就代表接受不到了
                    event.data.fd = sockfd;
                    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);   

                    netfd = -1;
                    break;
                }
                send(netfd,buf,sizeof(buf),0);
            }
            else if(readset[i].data.fd == netfd)
            {
                bzero(buf,sizeof(buf));
                ssize_t sret = recv(netfd,buf,sizeof(buf),0);
                if(sret == 0)
                {
                    //对面想退出
                    printf("hehe\n");
                    //移除监听
                    epoll_ctl(epfd,EPOLL_CTL_DEL,netfd,NULL);
                    epoll_ctl(epfd,EPOLL_CTL_DEL,STDIN_FILENO,NULL);
                    //增加sockfd
                    event.events = EPOLLIN;
                    event.data.fd = sockfd;
                    epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&event);
                    close(netfd);
                    netfd = -1;
                    break;
                }
                printf("buf = %s\n",buf);
            }
        }
    }
    return 0;
}